/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2023.
 * Description: header for rtos_mm_struct extend support
 * Author: nixiaoming
 * Create: 2018-2-13
 */

#ifndef _RTOS_MM_TYPES_H_
#define _RTOS_MM_TYPES_H_

#ifdef CONFIG_RTOS_MM_EXTEND
#include <linux/sched.h>
#include <linux/mm_types.h>
#ifdef CONFIG_RTOS_IDUMP
#include <linux/idump_mm_extend.h>
#endif
#ifdef CONFIG_RTOS_MEM_SNAPSHOT
#include <linux/rtos_mem_snapshot.h>
#endif

#define RTOS_MM_HUAGEPAGE_SHARED 1

struct rtos_mm_struct {
	/* Add a new member for mm_struct here */
#ifdef CONFIG_RTOS_IDUMP
	struct idump_mm_extend idump;
#endif
#ifdef CONFIG_RTOS_COREDUMP_ON_EXIT
	int dump_on_exit;
#endif
#ifdef CONFIG_RTOS_MEM_HUGEPAGE_SHARED_LIB
	unsigned int hugepage_shared;
#endif
#ifdef CONFIG_RTOS_RO_VMA_HASH
	unsigned long ro_vma_hash_jiffies;
#endif
#ifdef CONFIG_RTOS_MEM_SNAPSHOT
	struct mem_snapshot_task *cma_task[MAX_CMA_AREAS];
#endif
};

/* It is strictly forbidden to modify this structure */
struct rtos_mm_extend {
	struct rtos_mm_struct rtos;
	struct mm_struct mm; /* It is strictly forbidden to modify mm_struct */
	/*
	 * cpu_bitmap in mm_struct is dynamically sized based on nr_cpu_ids,
	 * so, the mm_cpumask needs to be at the end of mm_struct, and
	 * mm_struct needs to be at the end of rtos_mm_struct as well.
	 */
};

extern struct rtos_mm_struct rtos_init_mm;

/*
 * The caller needs to guarantee mm != NULL,
 * The function does not return a failure
 */
static inline struct rtos_mm_struct *mm_to_rtos_mm(struct mm_struct *mm)
{
	struct rtos_mm_extend *mm_extend;

	BUG_ON(!mm);
	if (mm == &init_mm)
		return &rtos_init_mm;
	mm_extend = container_of(mm, struct rtos_mm_extend, mm);
	return &mm_extend->rtos;
}

static inline unsigned int rtos_extend_mm_size(void)
{
	return sizeof(struct rtos_mm_extend) - sizeof(struct mm_struct);
}

extern void rtos_mm_struct_init(struct mm_struct *mm);

#else
#define rtos_mm_struct mm_struct
#define mm_to_rtos_mm(x) (x)

static inline void rtos_mm_struct_init(struct mm_struct *mm)
{
}

#endif

#endif
